Be more careful with floating point divisions
authorMatthias Clasen <mclasen@redhat.com>
Fri, 8 Jan 2016 18:17:58 +0000 (13:17 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 8 Jan 2016 18:17:58 +0000 (13:17 -0500)
The assumption that MIN() takes care of all infinities here
turns out to be wrong. We were getting inf and -nan for some
combinations of 0 width/height and corners, leading to invalid
matrices and cairo errors.

https://bugzilla.gnome.org/show_bug.cgi?id=759668

gtk/gtkroundedbox.c

index 3d2befe658e655979873b48ac33ddbdbd5b86e61..b63b7d51e5084e7aeb5d8c413532956f9dd902ed 100644 (file)
@@ -56,16 +56,23 @@ static void
 gtk_rounded_box_clamp_border_radius (GtkRoundedBox *box)
 {
   gdouble factor = 1.0;
+  gdouble corners;
 
-  /* note: division by zero leads to +INF, which is > factor, so will be ignored */
-  factor = MIN (factor, box->box.width / (box->corner[GTK_CSS_TOP_LEFT].horizontal +
-                                          box->corner[GTK_CSS_TOP_RIGHT].horizontal));
-  factor = MIN (factor, box->box.height / (box->corner[GTK_CSS_TOP_RIGHT].vertical +
-                                           box->corner[GTK_CSS_BOTTOM_RIGHT].vertical));
-  factor = MIN (factor, box->box.width / (box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal +
-                                          box->corner[GTK_CSS_BOTTOM_LEFT].horizontal));
-  factor = MIN (factor, box->box.height / (box->corner[GTK_CSS_TOP_LEFT].vertical +
-                                           box->corner[GTK_CSS_BOTTOM_LEFT].vertical));
+  corners = box->corner[GTK_CSS_TOP_LEFT].horizontal + box->corner[GTK_CSS_TOP_RIGHT].horizontal;
+  if (corners != 0)
+    factor = MIN (factor, box->box.width / corners);
+
+  corners = box->corner[GTK_CSS_TOP_RIGHT].vertical + box->corner[GTK_CSS_BOTTOM_RIGHT].vertical;
+  if (corners != 0)
+    factor = MIN (factor, box->box.height / corners);
+
+  corners = box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal + box->corner[GTK_CSS_BOTTOM_LEFT].horizontal;
+  if (corners != 0)
+    factor = MIN (factor, box->box.width / corners);
+
+  corners = box->corner[GTK_CSS_TOP_LEFT].vertical + box->corner[GTK_CSS_BOTTOM_LEFT].vertical;
+  if (corners != 0)
+    factor = MIN (factor, box->box.height / corners);
 
   box->corner[GTK_CSS_TOP_LEFT].horizontal *= factor;
   box->corner[GTK_CSS_TOP_LEFT].vertical *= factor;